package com.hdax.dm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.Common;
import com.aliyun.teautil.models.RuntimeOptions;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hdax.dm.common.utils.CommonResponse;
import com.hdax.dm.common.utils.ResponseUtil;
import com.hdax.dm.constants.ResultEnumCode;
import com.hdax.dm.dtos.user.UserDto;
import com.hdax.dm.entity.user.DmUser;
import com.hdax.dm.exceptions.DmException;
import com.hdax.dm.mappers.DmUserMapper;
import com.hdax.dm.mapstructs.UserDtoMapper;
import com.hdax.dm.service.UserLoginService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class UserLoginServiceImpl extends ServiceImpl<DmUserMapper, DmUser> implements UserLoginService {

    @Autowired
    private UserDtoMapper userDtoMapper;

    private DmUser getUser(String phone) throws DmException{
        LambdaQueryWrapper<DmUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DmUser::getPhone,phone);
        DmUser loginUser = baseMapper.selectOne(wrapper);
        if(loginUser == null){
            throw new DmException(ResultEnumCode.LOGIN_PHONE_ERR);
        }
        return loginUser;
    }
    @Override
    public CommonResponse<UserDto> login(String phone, String password) throws DmException {

        DmUser loginUser = getUser(phone);
        if(!loginUser.getPassword().equals(password)){
            throw new DmException(ResultEnumCode.LOGIN_PASSWORD_ERR);
        }
        UserDto userDto = userDtoMapper.toTarget(loginUser);
        return ResponseUtil.returnSuccess(userDto);
    }


    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    private static final int VCODE_TIME_LIMIT = 60;
    private static final TimeUnit TIME_UNIT = TimeUnit.SECONDS;

    @Override
    public CommonResponse<UserDto> login(String phone) throws DmException {
        DmUser loginUser = getUser(phone);
        if(loginUser == null){
            throw new DmException(ResultEnumCode.LOGIN_PHONE_ERR);
        }
        UserDto userDto = userDtoMapper.toTarget(loginUser);
        return ResponseUtil.returnSuccess(userDto);
    }


    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Override
    public String generateVCode(String phoneNumber) throws DmException {
        //验证手机号格式是否正确
        if (!phoneNumber.matches("^1[3-9]\\d{9}$")) {
            throw new DmException(ResultEnumCode.LOGIN_MSG_ERROR);
        }
        //检查是否已经获取了验证码
        String vcode = stringRedisTemplate.opsForValue().get("vcode:" + phoneNumber);
        if(vcode!=null){
            throw new DmException(ResultEnumCode.LOGIN_EXISTS_VCODE_ERROR);
        }
        //根据手机号查询相应用户信息，并判断用户是否存在
        this.login(phoneNumber);
        //随机生成一个四位数的验证码
        Random random = new Random();
        int rand = random.nextInt(1000,10000);
        //向消息中间件发送消息
        Map<String,String> params = new HashMap<>();
        params.put("phoneNumber",phoneNumber);
        params.put("vcode",rand+"");
        //rabbitTemplate.convertAndSend("dmsms",params);
        //存储验证码到redis
        stringRedisTemplate.opsForValue().set("vcode:"+phoneNumber,rand + "",VCODE_TIME_LIMIT,TIME_UNIT);
        return String.valueOf(rand);
    }

    @Override
    public CommonResponse<UserDto> msgLogin(String phoneNumber, String vcode) throws DmException {
        //验证手机号格式是否正确
        if (!phoneNumber.matches("^1[3-9]\\d{9}$")) {
            throw new DmException(ResultEnumCode.LOGIN_MSG_ERROR);
        }
        //检查是否已经获取了验证码
        String cacheVCode = stringRedisTemplate.opsForValue().get("vcode:" + phoneNumber);
        if(cacheVCode==null){
            throw new DmException(ResultEnumCode.LOGIN_NOT_EXISTS_VCODE_ERROR);
        }
        if(!cacheVCode.equals(vcode)){
            throw new DmException(ResultEnumCode.LOGIN_NOT_EXISTS_VCODE_ERROR);
        }
        DmUser loginUser = getUser(phoneNumber);
        if(loginUser == null){
            throw new DmException(ResultEnumCode.LOGIN_PHONE_ERR);
        }
        UserDto userDto = userDtoMapper.toTarget(loginUser);
        return ResponseUtil.returnSuccess(userDto);
    }


}
